/*
 * main.h
 *
 *  Created on: 10/10/2011
 *      Author: utn_so
 */

#ifndef MAIN_H_
#define MAIN_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <fuse.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <semaphore.h>
#include <unicode/utypes.h>
#include <unicode/ustring.h>
#include <poll.h>
#include <pthread.h>
#include <time.h>
#include "config.h"
#include "log.h"
#include "sockets.h"

#define pathCfg "/home/utn_so/Desarrollo/Workspace/PRAID/Debug/CfgRAID.cfg"
#define ENVIADO 0x77
#define ESPERA 0x78
#define ERROR 0x80


typedef struct {
	int32_t puertoFS;
	int32_t puertoPD;
	int32_t flagConsola;
}tConfig;

typedef struct Nodo{
	int32_t nroSocketFS, estado;
	t_NIPC paquete;
	struct Nodo *siguiente;
} tNodo;

typedef struct {
	tNodo *ant, *post;
} tCola;

typedef struct StructSem {
	sem_t semaforoDisco;
	pthread_mutex_t bloqueaColaDisco;
	pthread_mutex_t bloqueaCantPedidos;
} tStructSem;

typedef struct NodoLista {
	int32_t idDisco;
	int32_t nroSocketPD, cantPedidos, sincro;
	tCola *colaDisco;
	tStructSem semaforos;
	struct NodoLista *siguiente;
} tNodoLista;

typedef struct Lista {
	tNodoLista *head;
} tLista;

typedef struct DiscoCHS {
	int32_t c;
	int32_t h;
	int32_t s;
} tDiscoCHS;


/*              configPRAID             */

tConfig abrirArchivoConfig ();

/*         funcionesPRAID        */

void inicializarSemaforosYMutex ();
void crearColaGral();
void crearListaDiscos();
tCola *crearColaPeticiones ();
void discosConectados ();
void encolarPeticionColaGral (int32_t socket, int32_t estado, t_NIPC paquete);
void desencolarPeticionColaGral (int32_t *socket, int32_t *estado, t_NIPC *paquete);
void encolarPeticionColaDisco (tCola *cola, int32_t socket, int32_t estado, t_NIPC paquete);
void buscarNodosSinSincroYEncola (int32_t socket, int32_t estado, t_NIPC paquete);
int32_t encolarEnTodosLosDiscos (int32_t socket, int32_t estado, t_NIPC paquete);
void encolarPedidoLectura (int32_t socket, int32_t estado, t_NIPC paquete);
void buscarPaqueteYDesencolar (t_NIPC paquete, tNodoLista *ptrDisco, int32_t *socket, int32_t *estado);
void actualizarBitVector (int32_t **bitVector, t_NIPC paquete, int32_t tamBitVector);
int32_t bitVectorCompleto(int32_t *bitVector, int32_t tamBitVector);
void desencolarDisco (int32_t nroSocketPD);
int32_t algunDiscoSincronizado();
void redistribuirPedidosDiscoCaido (tCola *colaDePeticiones);
int32_t *parsearSectores(char *cadenaAseparar, int32_t *cantidad);

/* 			conexion		*/

void setearFD (struct pollfd *descriptores,int32_t nroSocketFS);
void distribuirPedidos ();
tNodoLista *agregarDisco (int32_t nroSocketPD, int32_t *idDisco);
void iniciarComunicacionPD (void *disco);
void recibirPedidosFS(int32_t descriptorFS,t_NIPC paquete);
int32_t enviarPeticionesADisco (int32_t nroSocketPD, tCola *colaDePeticiones, int32_t idDisco, tNodoLista *disco);
int32_t recibirRespuestasPD (int32_t socketConexionPD, tNodoLista *ptrDisco, int32_t *cantParcialSincronizada, int32_t **bitVector, int32_t contador, int32_t tamBitVector);
void seCayoUnDisco (int32_t nroSocketPD, tCola *colaDePeticiones);
int32_t handshakePPD (int32_t socketPD, int32_t *idDisco);
int32_t handshakePFS (int32_t socketFS, int32_t *idDisco);

#endif /* MAIN_H_ */
